﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using PostSharp.Aspects;
using PostSharp.Aspects.Dependencies;

namespace GrayParrot.Infrastructure
{
    [Serializable]
    [AspectTypeDependency(AspectDependencyAction.Order, AspectDependencyPosition.After, typeof(WithExceptionHandling))]
    [AspectTypeDependency(AspectDependencyAction.Order, AspectDependencyPosition.After, typeof(WithTrace))]
    [AspectTypeDependency(AspectDependencyAction.Order, AspectDependencyPosition.After, typeof(WithActivityLog))]
    //[AspectTypeDependency(AspectDependencyAction.Order, AspectDependencyPosition.After, typeof(WithCache))]
    public class WithTransaction : OnMethodBoundaryAspect, IDisposable
    {
        [NonSerialized]
        TransactionScope TransactionScope;

        public WithTransaction()
        {

        }

        public override void OnEntry(MethodExecutionArgs args)
        {
            this.TransactionScope = new TransactionScope(TransactionScopeOption.RequiresNew);
        }

        public override void OnSuccess(MethodExecutionArgs args)
        {
            this.TransactionScope.Complete();
        }

        public override void OnException(MethodExecutionArgs args)
        {
            args.FlowBehavior = FlowBehavior.Continue;
            Transaction.Current.Rollback();

            GrayParrot.Logging.Logger.For(args.Instance.GetType()).Error("Transaction Was Unsuccessful!", args.Exception); 
        }

        public override void OnExit(MethodExecutionArgs args)
        {
            this.TransactionScope.Dispose();
        }

        public void Dispose()
        {
            if (TransactionScope != null)
            {
                this.TransactionScope.Dispose();
            }
        }
    }
}
